// src/composables/useTasks.js
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue';
import { get, post } from '@/axios/api';
import { useRouter } from 'vue-router';

export function useTasks({ pageSize = 10, initialPollMs = 2000, maxPollMs = 30000, wsEnabled = true } = {}) {
    const tasks:any = ref([]);
    const loading = ref(false);
    const error = ref(null);
    const page = ref(1);
    const pageSizeRef = ref(pageSize);
    const total = ref(0);
    const search = ref('');
    const router = useRouter();

    // polling state
    let pollTimer:any = null;
    let pollMs = initialPollMs;
    let consecutiveFailures = 0;
    let stoppedByVisibility = false;

    const unfinishedSet = new Set(['PENDING', 'STARTED', 'RUNNING']);

    const unfinishedIds = computed(() =>
        tasks.value.filter((t: any) => unfinishedSet.has(t.status)).map((t: any) => t.id)
    );

    function buildListParams() {
        const params:any = {
            page: page.value,
            page_size: pageSizeRef.value
        };
        if (search.value) params.search = search.value;
        return params;
    }

    async function fetchList() {
        loading.value = true;
        error.value = null;
        try {
            const res:any = await get('/usertasks/', { params: buildListParams() });
            // assume paginated { results: [...], count: N }
            tasks.value = res.results;
            total.value = res.count ?? tasks.value.length;
            // if there are unfinished tasks, ensure polling or ws listened
            if (unfinishedIds.value.length > 0) {
                startPollingIfNeeded();
            } else if (unfinishedIds.value.length === 0) {
                stopPolling();
            }
        } catch (err:any) {
            error.value = err;
            console.error('fetchList error', err);
        } finally {
            loading.value = false;
        }
    }

    // batch status check: POST /api/usertasks/batch_status/ { ids: [...] }
    async function pollUnfinishedOnce() {
        if (unfinishedIds.value.length === 0) {
            stopPolling();
            return;
        }
        try {
            const res:any = await post('/usertasks/batch_status/', { ids: unfinishedIds.value });
            const map = res; // { "id1": {...}, "id2": {...} }
            // merge updates into tasks array
            for (const [k, v] of Object.entries(res)) {
                map[k.replace(/-/g, '')] = v;
            }
            tasks.value = tasks.value.map((t:any) => {
                const updated = map[String(t.id)];
                return updated ? { ...t, ...updated } : t;
            });
            consecutiveFailures = 0;
            pollMs = Math.max(initialPollMs, initialPollMs * 2 ** Math.max(0, consecutiveFailures - 1));
            if (unfinishedIds.value.length === 0) stopPolling();
        } catch (err) {
            console.error('pollUnfinishedOnce error', err);
            consecutiveFailures += 1;
            // exponent backoff up to maxPollMs
            pollMs = Math.min(maxPollMs, initialPollMs * 2 ** consecutiveFailures);
        }
    }


    async function scheduleNextPoll() {
        // 清理旧定时器（保险）
        if (pollTimer) {
            clearTimeout(pollTimer);
            pollTimer = null;
        }

        // 如果页面不可见或没有未完成任务，则不调度
        if (document.hidden || unfinishedIds.value.length === 0) return;

        pollTimer = setTimeout(async () => {
            await pollUnfinishedOnce();
            // 只有在仍有未完成任务并且页面可见时继续调度
            if (!document.hidden && unfinishedIds.value.length > 0) {
                scheduleNextPoll();
            } else {
                pollTimer = null;
            }
        }, pollMs);
    }

    function startPollingIfNeeded() {
        if (pollTimer) return;
        if (unfinishedIds.value.length === 0) return;
        // 立即执行一次，然后调度后续
        pollUnfinishedOnce().then(() => {
          // 如果还有未完成任务，再启动循环
          if (unfinishedIds.value.length > 0 && !document.hidden) {
            scheduleNextPoll();
          }
        });
    }
    function stopPolling() {
        if (pollTimer) {
            clearInterval(pollTimer);
            pollTimer = null;
        }
    }

    // Page Visibility handling: stop polling when page hidden
    function handleVisibilityChange() {
        if (document.hidden) {
            // 页面切到后台，暂停轮询（节省资源）
            stoppedByVisibility = true;
            stopPolling();
        } else {
            // 页面回到前台，若之前有未完成任务则恢复
            if (stoppedByVisibility) {
                stoppedByVisibility = false;
                if (unfinishedIds.value.length > 0) startPollingIfNeeded();
            }
        }
    }

    // actions
    async function refreshList() {
        await fetchList();
    }

    async function gotoResult(task:any) {
        router.push({ name: 'TaskResult', params: { id: task.id } });
    }

    async function cancelTask(task:any) {
        try {
            await post(`/usertasks/${task.id}/cancel/`);
            // update local state
            task.status = 'CANCELLED';
            // optionally refetch
            fetchList();
        } catch (e) {
            console.error('cancel error', e);
            throw e;
        }
    }

    // watch search/page changes
    watch([page, pageSizeRef, search], () => fetchList());

    onMounted(() => {
        document.addEventListener('visibilitychange', handleVisibilityChange);
        fetchList().then(() => {
            if (unfinishedIds.value.length > 0 && !document.hidden) {
                startPollingIfNeeded();
            }
        });
    });

    onBeforeUnmount(() => {
        stopPolling();
        document.removeEventListener('visibilitychange', handleVisibilityChange);
    });

    return {
        tasks,
        loading,
        error,
        page,
        pageSize: pageSizeRef,
        total,
        search,
        refreshList,
        gotoResult,
        cancelTask,
    };
}
